# uncompyle6 version 3.6.1
# Python bytecode 2.7 (62211)
# Decompiled from: Python 3.6.5 |Anaconda, Inc.| (default, Mar 29 2018, 13:32:41) [MSC v.1900 64 bit (AMD64)]
# Embedded file name: abcft_algorithm_deploy_renshou/iqa.py
# Compiled at: 2020-04-27 21:44:40
import cv2, time, logging
from math import *
from main_v3.utils import *
log = logging.getLogger(__name__)

root = os.path.dirname(os.path.abspath(__file__))

def calcul_gradient_score(gray_image):
    u"""
    描述： 针对传输来的图像进行水平和垂直方向的梯度计算，计算梯度的平均得分，
           从而给出输入图像的清晰度得分
    """
    hori = cv2.Sobel(gray_image, cv2.CV_64F, 1, 0)
    vert = cv2.Sobel(gray_image, cv2.CV_64F, 0, 1)
    assement_weight = 1.0
    fx, fy = hori * hori, vert * vert
    dst = np.sqrt(fx + fy)
    dst = cv2.normalize(dst, None, 0, 255, cv2.NORM_MINMAX)
    mean_val = np.mean(dst)
    final_score_ori = np.sqrt(np.mean((dst - mean_val) * (dst - mean_val)))
    final_score = final_score_ori * assement_weight
    xmin, xmax = (20.0, 80.0)
    map_min, map_max = (0.0, 1.0)
    if final_score >= xmax:
        final_score = xmax - 1
    if final_score <= xmin:
        final_score = xmin + 1
    final_score = map_min + (map_max - map_min) / (xmax - xmin) * (final_score - xmin)
    return final_score


def gradient_assessment(gray_image, bgr_image, maser_th):
    u"""
    描述： 利用MSER获取文本外接矩形框，过滤掉重复的内嵌矩形后，通过连通区域调用梯度计算函数，
    最终返回梯度数值
    """
    mser_image = cv2.MSER_create(_min_area=maser_th, _max_variation=0.7)
    regions, boxes = mser_image.detectRegions(gray_image)
    hulls = [ cv2.convexHull(p.reshape(-1, 1, 2)) for p in regions ]
    vis = bgr_image.copy()
    cv2.polylines(vis, hulls, 1, (0, 255, 0))
    height, width = gray_image.shape
    mask = np.zeros((height, width), np.uint8)
    for contour in hulls:
        cv2.drawContours(mask, [contour], -1, (255, 255, 255), -1)

    cc_info = find_connection_region(mask)
    bbox_list = cc_info['CC_POS']
    mean_score = 0.0
    if len(bbox_list) == 0:
        return mean_score
    for box in bbox_list:
        xmin, ymin = box[0], box[1]
        xmax, ymax = box[2], box[3]
        crop_text_img = gray_image[ymin:ymax, xmin:xmax]
        final_score = calcul_gradient_score(crop_text_img)
        mean_score += final_score

    mean_score = mean_score / len(bbox_list)
    return mean_score


def gradient_assement_simple(gray_image, maser_th):
    u"""
    描述： 简易版本的梯度计算，这里直接利用MSER给出来的boxes，直接利用这些框进行梯度得分的计算
    """
    mser_image = cv2.MSER_create(_min_area=maser_th, _max_variation=0.7)
    _, boxes = mser_image.detectRegions(gray_image)
    mean_score = 0.0
    for bbox in boxes:
        xmin, ymin = bbox[0], bbox[1]
        xmax, ymax = bbox[0] + bbox[2], bbox[1] + bbox[3]
        crop_text_img = gray_image[ymin:ymax, xmin:xmax]
        final_score = calcul_gradient_score(crop_text_img)
        mean_score += final_score

    mean_score = mean_score / len(boxes)
    return mean_score


def image_quality_assessment(image_ori, score_th=0.6):
    u"""
    描述： 根据获取到的原始图像进行缩放提速，利用MSER算法获取文本矩形框，
    计算这些矩形框内部的梯度得分，从而判断整张图像的清晰度。
    注意：代码需要利用网格搜索的参数有2个，得分阈值和MSER面积阈值
    """
    log.info('-----BLUR_THRESHOLD------ : %s' % str(score_th))
    height, width, _ = image_ori.shape
    max_size_th = 1500
    if max(height, width) > max_size_th:
        ratio = float(max_size_th) / max(height, width)
        image_ori = cv2.resize(image_ori, None, fx=ratio, fy=ratio, interpolation=cv2.INTER_NEAREST)
    image_gray = cv2.cvtColor(image_ori, cv2.COLOR_BGR2GRAY)
    if max(height, width) >= 1000:
        mean_score = gradient_assessment(image_gray, image_ori, 100)
    else:
        mean_score = gradient_assessment(image_gray, image_ori, 80)
    if mean_score > score_th:
        status = 0
    else:
        status = 1
    return (
     status, mean_score)


if __name__ == '__main__':
    image_file_path = os.path.join(root, "../datasets", "grd_test", "fuzzy words")
    save_path1 = os.path.join(root, "../outputs", "1_clear_wrong/")
    save_path2 = os.path.join(root, "../outputs", "2_blur_wrong/")
    all_file_path = os.listdir(image_file_path)
    for path_single in all_file_path:
        if '.jpg' in path_single or ".jpeg" in path_single:
            path = os.path.join(image_file_path,path_single)

            image = cv2.imread(path)
            start = time.time()
            status, confidence = image_quality_assessment(image)
            print(status,confidence)
            print('  -- > final_time is %f\n' % (time.time() - start))
            base_name = os.path.basename(path)
            if status == 0:
                txt = str(confidence)
                cv2.putText(image, txt, (30, 30), cv2.FONT_HERSHEY_COMPLEX, 1.0, (0,
                                                                                  0,
                                                                                  255), 3)
                cv2.imwrite(save_path2 + base_name, image)
            else:
                txt = str(confidence)
                cv2.putText(image, txt, (30, 30), cv2.FONT_HERSHEY_COMPLEX, 1.0, (0,
                                                                                  0,
                                                                                  255), 3)
                cv2.imwrite(save_path1 + base_name, image)